/*
 * 作者		www.TheWk.cn.vc
 * 开发环境	Windows7 64位 MyEclipse8.6 JDK1.6.0_37
 * 开发日期	2013-11-13
 */
package common.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

import common.exception.CustomException;

/**
 * <hr/>
 * 
 * @author www.TheWk.cn.vc
 * @version 1.0 2013-11-13
 * @class common.utils.DateUtils
 */
public abstract class DateUtils {

	private static final DateFormat DFYYYYMMDD = new SimpleDateFormat("yyyyMMdd");
	private static final DateFormat DFYYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");
	private static final DateFormat DFYYYY_MM_DD4China = new SimpleDateFormat("yyyy年MM月dd日");
	private static final DateFormat DFYYYY_MM4China = new SimpleDateFormat("yyyy年MM月");
	private static final DateFormat DFyyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
	private static final DateFormat DFyyyy_MM_dd_HHmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static final DateFormat DFyyyy_MM = new SimpleDateFormat("yyyy年MM月");
	private static final DateFormat DFyyyyMMddHHmmssSSS = new SimpleDateFormat(
			"yyyyMMddHHmmssSSS");
	private static SimpleDateFormat sdf = new SimpleDateFormat();

	private DateUtils() {

	}

	/**
	 * 获取昨天的日期
	 */
	public static Date getYesterday() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		return calendar.getTime();
	}

	/**
	 * 获取明天的日期
	 */
	public static Date getTomorrow() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		return calendar.getTime();
	}

	/**
	 * 传入日期,增减该日期的秒数
	 */
	public static Date addSeconds(Date source, int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(source);
		calendar.add(Calendar.SECOND, seconds);
		return calendar.getTime();
	}

	/**
	 * 传入日期,增减该日期的天数
	 */
	public static Date addDays(Date source, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(source);
		calendar.add(Calendar.DATE, days);
		return calendar.getTime();

	}

	/**
	 * 传入日期,增减该日期的月份
	 */
	public static Date addMonths(Date source, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(source);
		calendar.add(Calendar.MONTH, month);
		return calendar.getTime();
	}

	/**
	 * 获取当天日期的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFYYMMDD(Date date) {
		return DFYYYYMMDD.format(date);
	}
	/**
	 * 获取当天日期的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFYYMM(Date date) {
		return DFyyyy_MM.format(date);
	}
	
	/**
	 * 获取yyyy-MM-dd格式的字符串
	 * yyyy-MM-dd
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFYYYY_MM_DD(Date date) {
		return DFYYYY_MM_DD.format(date);
	}
	/**
	 * 获取yyyy年MM月dd日格式的字符串
	 * yyyy年MM月dd日
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFYYYY_MM_DD4China(Date date) {
		return DFYYYY_MM_DD4China.format(date);
	}
	/**
	 * 获取yyyy年MM月格式的字符串
	 * yyyy年MM月
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFYYYY_MM4China(Date date) {
		return DFYYYY_MM4China.format(date);
	}
	
	/**
	 * 获取yyyy_MM_dd_HHmmss格式的字符串
	 * yyyy_MM_dd HH:mm:ss
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFyyyy_MM_dd_HHmmss(Date date) {
		return DFyyyy_MM_dd_HHmmss.format(date);
	}
	/**
	 * 获取当天包含毫秒的日期的字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getFormatStringByDFyyyyMMddHHmmssSSS(Date date) {
		return DFyyyyMMddHHmmssSSS.format(date);
	}
	
	public static String getFormatStringByDFyyyyMMddHHmmss(Date date) {
		return DFyyyyMMddHHmmss.format(date);
	}

	/**
	 * 比较两个日期是否同一天
	 * 
	 * @param day1
	 * @param day2
	 * @return
	 */
	public static boolean isSameDay(Date day1, Date day2) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String ds1 = sdf.format(day1);
		String ds2 = sdf.format(day2);
		if (ds1.equals(ds2)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 比较两个日期 相差的的天数，不管小时数。即使今天23点和明天1点之间也是1天
	 * oDate-fDate
	 * @param fDate
	 * @param oDate
	 * @return
	 */
	public static int daysOfTwo(Date fDate, Date oDate) {
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(fDate);
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
		aCalendar.setTime(oDate);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		int result = day2-day1;
		return result;
	}
	
	/** 
	 * 比较两个日期之间的大小 
	 *  
	 * @param d1 
	 * @param d2 
	 * @return 前者大于后者返回true 反之false 
	 */  
	public static boolean compareDate(Date d1, Date d2) {  
	    Calendar c1 = Calendar.getInstance();  
	    Calendar c2 = Calendar.getInstance();  
	    c1.setTime(d1);  
	    c2.setTime(d2);  
	  
	    int result = c1.compareTo(c2);  
	    if (result >= 0)  
	        return true;  
	    else  
	        return false;  
	}  
	
	/**
	 * 比较两个日期 相差的的秒数
	 * oDate-fDate
	 * @param fDate
	 * @param oDate
	 * @return
	 */
	public static Long minsOfTwo(Date fDate, Date oDate) {
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(fDate);
		Long time1 = aCalendar.getTime().getTime();
		aCalendar.setTime(oDate);
		Long time2 = aCalendar.getTime().getTime();
		return time2 - time1;
	}
	/**
	 * 获取清算规定格式的开始日期
	 * yyyy-MM-dd 00:00:00
	 * @param date
	 * @return
	 */
	public static Date parseSquareStartTime(Date date){
		String str = getFormatStringByDFYYYY_MM_DD(date);
		String pattern = "yyyy-MM-dd HH:mm:ss";
		str += " 00:00:00";
		return parseDateFormat(str, pattern);
	}
	/**
	 * 获取清算规定格式的结束日期
	 * yyyy-MM-dd 23:59:59
	 * @param date
	 * @return
	 */
	public static Date parseSquareEndTime(Date date){
		String str = getFormatStringByDFYYYY_MM_DD(date);
		String pattern = "yyyy-MM-dd HH:mm:ss";
		str += " 23:59:59";
		return parseDateFormat(str, pattern);
	}
	/**
	 * 获取清算月规定格式的开始日期
	 * yyyy-MM-dd （每月的第一天）
	 * @param date
	 * @return
	 */
	public static Date parseSquareMonthStartTime(Date date){
		String str = getFormatCustomDateString(date, "yyyy-MM");
		String pattern = "yyyy-MM-dd";
		str += "-01";
		return parseDateFormat(str, pattern);
	}
	/**
	 * 获取清算月规定格式的结束日期
	 * yyyy-MM-dd (下个月的第一天)
	 * @param date
	 * @return
	 */
	public static Date parseSquareMonthEndTime(Date date){
		date = addMonths(date, 1);
		String str = getFormatCustomDateString(date, "yyyy-MM");
		String pattern = "yyyy-MM-dd";
		str += "-01";
		return parseDateFormat(str, pattern);
	}
	/**
	 * 根据日期和格式转换为规定格式的日期
	 * pattern 为空则使用默认格式：yyyy-MM-dd
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static Date parseDate2Date(Date date,String pattern){
		 String partternStr = StringUtils.isNotBlank(pattern)?pattern:"yyyy-MM-dd";
		 SimpleDateFormat sdf = new SimpleDateFormat(partternStr);
		 String str = sdf.format(date);
	     return parseDateFormat(str, partternStr);
	}
	public static Date parseDateFormat(String strDate)
    {
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return parseDateFormat(strDate, pattern);
    }
	public static synchronized Date parseDateFormat(String strDate, String pattern)
    {
        synchronized (sdf)
        {
            Date date = null;
            sdf.applyPattern(pattern);
            try
            {
                date = sdf.parse(strDate);
            }
            catch (Exception e)
            {
            }
            return date;
        }
    }

	/**
	 * 根据pattern获取自定义时间
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String getFormatCustomDateString(Date date,String pattern) {
		if(StringUtils.isBlank(pattern)){
			return DFYYYY_MM_DD.format(date);
		}
		sdf.applyPattern(pattern);
		return sdf.format(date);
	}
	
	/**
	 * 比较时间差
	 * 只适用于格式为：yyyy-mm-dd的日期
	 */
	public static long betweenDays(Date date,Date date1){
 		long diff = date1.getTime()-date.getTime();
		long days = diff/(1000*60*60*24);
		return days;
	}
	
	/**
	 * 获取月差值
	 * @param start
	 * @param end
	 * @return
	 */
	 public static int getMonth(Date start, Date end) {
		if (start.after(end)) {
			 throw new CustomException("结束月份小月开始月份！");
		}
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);

        int year = endCalendar.get(Calendar.YEAR)- startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH)- startCalendar.get(Calendar.MONTH);

        if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
    }
	
	public static void main(String[] args) {
//		Date date1 = new Date();
//		Date date1 = parseDateFormat("2015-02-20 00:00:01");
//		Date date2 = parseDateFormat("2014-03-19 23:59:59");
		Date startSquareTime = parseDateFormat("2015-01-16 00:00:00","yyyy-MM-dd");
		Date endSquareTime = parseDateFormat("2017-01-15 00:00:00","yyyy-MM-dd");
//		System.out.println(betweenDays(startSquareTime,endSquareTime));
//		System.out.println(daysOfTwo(startSquareTime,endSquareTime));
//		System.out.println(minsOfTwo(parseDate2Date(startSquareTime,null),parseDate2Date(endSquareTime,null)));
		System.out.println(getMonth(startSquareTime,endSquareTime));
//		System.out.println(getFormatStringByDFYYYY_MM_DD(addMonths(startSquareTime, -13)));
	}

}
